MacOS X Developer Preview 4 Release Notes Copyright © 2000 by Apple Computer, Inc. All Rights Reserved.
MallocDebug is a utility for measuring the dynamic memory usage of applications and for finding memory leaks. You can use MallocDebug to measure and analyze all allocated memory in an application or to measure the memory allocated since a given point in time. MallocDebug also contains a conservative garbage detector that can be used to detect "leaked" memory allocations that are no longer referenced by the application.
MallocDebug now allows you to inspect the contents of memory. Selecting any of the malloc blocks from the detailed listing brings up a hex dump of the contents of that memory. This can be particularly helpful if some (but not all) instances of a data structure are being leaked, and you'd like to see what the leaked instances have in common. It's also great fun for snooping around in memory to understand how memory in your application is laid out!
MallocDebug's Leaks mode allows you to find memory that is no longer referenced by your application. It accomplishes this by scanning through memory looking for values that may be pointers, then checking to see if the pointer references the beginning of a malloc-allocated block or a handle.
There are multiple definitions of "leaks" used by different tools in the Macintosh and non-Macintosh worlds. MallocDebug, like Rational's Purify and other tools, considers a leak to be a block of memory that your application cannot reference because pointers to it have been lost. The benefit of this definition is that you can find exactly which data structures are lost, and track down the cause. Metrowerks's Zone Ranger, by contrast, helps you find leaks by watching for your total memory usage to grow when performing a task that shouldn't change. Thus, Zone Ranger will identify cases where you may not be freeing the memory, but can still reference it -- perhaps because you're still using it, or perhaps because you don't realize you no longer need to keep it around. MallocDebug's stricter definition for leaks focuses your attention on definite problems. You can still identify cases of allocating unneeded memory by watching for new memory created, or an increase in the total memory size.
There are a few places where MallocDebug still misidentifies allocations as leaked. Allocations performed by malloc() and calloc() for GlobalCacheAllocate represent font caches that are incorrectly identified as leaks. Allocations in malloc() for NewBlock() are also incorrectly identified as leaks. The 64 kb allocation in NewHandle() is for a suballocator creating space to store handles. To hide these when examining leaks, select these allocations, then use the Prune->Path menu to remove them from MallocDebug's display.
MallocDebug misidentifies these allocated regions as leaks because the frameworks reference the regions with a pointer to an address starting several bytes after the beginning of the buffer. Because MallocDebug considers a buffer leaked if no pointers exist to the beginning of the buffer, these allocations are considered leaked. If your application uses similar techniques in data structures, MallocDebug may also detect occasional false leaks.
Applications crashing under MallocDebug usually indicate that the application is accessing freed memory, or referencing memory before or after the boundaries of the malloc block. These crashes occur because of two techniques to detect incorrect memory usage: clearing freed memory, and checking the status of guard words.
First, MallocDebug clears memory when a buffer is freed, filling the memory with the hexadecimal value 0x7F. If your application attempts to read freed memory, this ensures that the application will immediately use corrupt values, making the bug more obvious. Dereferencing a pointer in the cleared memory will immediately cause a bus error when the application tries to read the unmapped memory at 0x7F7F7F7F. This feature can be turned on and off in the Preferences panel. Changing the preference affects all programs launched by MallocDebug after changing the option.
Second, MallocDebug inserts a guard word before and after the malloc-allocated block to detect buffer overruns and underruns. 0xDEADBEEF is placed before the block, and 0xBEEFDEAD is placed after. MallocDebug checks these words occasionally; if they have been changed, MallocDebug marks the blocks as "trashed". Selecting the "Trashed nodes" mode allows you to see all blocks that had overruns or underruns that wrote to memory; the status field in the list of blocks also indicates blocks that have been trashed. Treating the guard bytes as pointers will also cause the application to crash. This feature cannot be turned off within MallocDebug.If your application is crashing in MallocDebug, you probably have a subtle, crash causing bug in your application; fix this immediately! The code may appear to work when run normally, but is likely to crash during long runs, thread timing changes, or other infrequent events. Isolate these bugs to improve the reliability of your code!
To track down the cause of the crash, first run the program in
MallocDebug with the "clear freed memory" option turned off. If the
program again works normally, the program probably referenced freed
memory. You can also run the application in gdb. gdb's attach
command will allow you to use the debugger to examine the application
already running under MallocDebug. Alternatively, you can run gdb,
then type "set env DYLD_INSERT_LIBRARIES
/usr/lib/libMallocDebug.A.dylib" to cause MallocDebug's malloc library
to be inserted into the application. Next, type "set start-with-shell 0",
(This option is needed to launch applications that immediately start new
threads; the libMallocDebug thread runs a thread in the background for
communicating with MallocDebug.)
Type "file
MallocDebug's "touched nodes" mode does not work in this release.
Some MallocDebug diagnostic messages (such as the application freeing memory already freed) get displayed to the console. Check the console for these helpful messages.